<?php

namespace app\data\service;

use app\admin\service\FeiShuService;
use app\admin\service\WorkUserService;
use app\admin\service\WxWorkOAService;
use think\admin\Service;
use think\facade\Log;

/**
 * 城市-员工关联
 * Class CityUserRelationService
 * @package app\data\service
 */
class CityUserRelationService extends Service
{
    /**
     * 获取城市师傅树
     * @return array
     */
    public function getCityUserTree($isPortal = true): array
    {
        $cityRelations = $this->app->db->name('data_city_relation')->field('id,from_province,from_city')->order('from_province desc, from_city desc')->select()->toArray();
        if ($isPortal) {
            $cityUserRelations = $this->app->db->name('data_city_user_relation')->where('group_power_status', 1)->select()->toArray();
        } else {
            $cityUserRelations = $this->app->db->name('data_city_user_relation')->select()->toArray();
        }

        $users = $this->app->db->name('work_user')->whereIn('id', array_column($cityUserRelations, 'uuid'))->field('id,open_id,user_id,name')->select()->toArray();
        foreach($users as $user) {
            $userId2User[$user['id']] = $user;
        }

        foreach ($cityUserRelations as $cityUserRelation) {
            $cityRelationId2User[$cityUserRelation['city_relation_id']][] = [
                'id' => $cityUserRelation['uuid'],
                'open_id' => $userId2User[$cityUserRelation['uuid']]['open_id'] ?? '',
                'user_id' => $userId2User[$cityUserRelation['uuid']]['user_id'] ?? '',
                'name' => $userId2User[$cityUserRelation['uuid']]['name'] ?? '',
            ];
        }

        foreach ($cityRelations as &$cityRelation) {
            $cityRelation['users'] = $cityRelationId2User[$cityRelation['id']] ?? [];
        }

        return $cityRelations;
    }

    /**
     * 返回打卡人数
     * @param $cityRelations
     * @return array
     */
    public function checkInUsers($cityRelations, $startTimestamp = null, $endTimestamp = null): array
    {
        foreach ($cityRelations as $cityRelation) {
            foreach ($cityRelation['users'] ?? [] as $item) {
                $users[] = $item['user_id'];
            }
        }

        $checkInUsers = [];
        if (!empty($users)) {
            $chunkUsers = array_chunk($users, 100);
            if (is_null($startTimestamp)) {
                $startTimestamp = strtotime(date('Y-m-d 00:00:00'));
            }
            if (empty($endTimestamp)) {
                $endTimestamp = time();
            }
            foreach ($chunkUsers as $chunkUser) {
                $checkInUsers = array_merge($checkInUsers, FeiShuService::instance()->checkInRecords($startTimestamp, $endTimestamp, $chunkUser));
            }
        }

        return $checkInUsers;
    }

    /**
     * 返回预警城市
     * @param $cityRecordNum
     * @param $checkInUsers
     * @param $cityRelations
     * @param $checkInUserCount
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function earlyWarningCities($todayMinDate, $todayMaxDate)
    {
        $records = $this->app->db->name('data_record')
            ->group('city_relation_id')
            ->field('city_relation_id,time_docking,COUNT(*) as count')
            ->where('time_docking', '>=', $todayMinDate)
            ->where('time_docking', '<=', $todayMaxDate)
            ->select()
            ->toArray();

        $cityUserRelations = $this->app->db->name('data_city_user_relation')
            ->group('city_relation_id')
            ->field('city_relation_id, sum(`limit`) as total_limit, online_status')
            ->where('online_status', 0)
            ->select()
            ->toArray();
        foreach ($cityUserRelations as $cityUserRelation) {
            $mapCityRelationId2limit[$cityUserRelation['city_relation_id']] = $cityUserRelation['total_limit'];
        }

        foreach ($records as $record) {
            if (!empty($record['city_relation_id'])) {
                if (!isset($mapCityRelationId2limit[$record['city_relation_id']])) {
                    $cityRelationIds[] = $record['city_relation_id'];
                } else {
                    if ($record['count'] > $mapCityRelationId2limit[$record['city_relation_id']]) {
                        $cityRelationIds[] = $record['city_relation_id'];
                    }
                }
            }
        }


        $cityUserRelations = $this->app->db->name('data_city_relation')
            ->whereIn('id', $cityRelationIds ?? [])
            ->select()
            ->toArray();

        return array_column($cityUserRelations, 'from_city');
    }

    /**
     * 保存城市员工关联
     * @param $cityRelationId
     * @param $uuids
     * @param $percentages
     * @return bool
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function save($cityRelationId, $uuids, $percentages, $limits, $groupPowerStatus, $onlineStatus)
    {
        foreach ($uuids as $key => $uuid) {
            $uuid = explode('#', $uuid);
            $uuid = $uuid[0] ?? 0;
            if (isset($percentages[$key])) {
                $uuid2percentages[$uuid] = $percentages[$key];
            }
            if (isset($limits[$key])) {
                $uuid2limits[$uuid] = $limits[$key];
            }
            if (isset($groupPowerStatus[$key])) {
                $uuid2GroupPowerStatus[$uuid] = $groupPowerStatus[$key];
            }
            if (isset($onlineStatus[$key])) {
                $uuid2GroupOnlineStatus[$uuid] = $onlineStatus[$key];
            }
        }

        $cityUserRelations = $this->app->db->name('data_city_user_relation')->where('city_relation_id', $cityRelationId)->select()->toArray();
        foreach ($cityUserRelations as $cityUserRelation) {
            if (!in_array($cityUserRelation['uuid'], $uuids)) {
                $deleteIds[] = $cityUserRelation['id'];
            } else {
                $percentage = $uuid2percentages[$cityUserRelation['uuid']] ?? 0;
                if ($cityUserRelation['percentage'] != $percentage) {
                    $update['percentage'] = $percentage;
                }

                $limit = $uuid2limits[$cityUserRelation['uuid']] ?? 0;
                if ($cityUserRelation['limit'] != $limit) {
                    $update['limit'] = $limit;
                }

                $groupPowerStatusOne = $uuid2GroupPowerStatus[$cityUserRelation['uuid']] ?? 0;
                if ($cityUserRelation['group_power_status'] != $groupPowerStatusOne) {
                    $update['group_power_status'] = $groupPowerStatusOne;
                }

                $onlineStatusOne = $uuid2GroupOnlineStatus[$cityUserRelation['uuid']] ?? 0;
                if ($cityUserRelation['online_status'] != $onlineStatusOne) {
                    $update['online_status'] = $onlineStatusOne;
                }

                if (!empty($update)) {
                    $this->app->db->name('data_city_user_relation')->where('id', $cityUserRelation['id'])->update($update);
                    unset($update);
                }

                $existUuids[] = $cityUserRelation['uuid'];
            }
        }

        foreach ($uuid2percentages ?? [] as $uuid => $percentage) {
            if (!in_array($uuid, $existUuids ?? [])) {
                $insertData[] = [
                    'city_relation_id' => $cityRelationId,
                    'uuid' => $uuid,
                    'percentage' => $percentage,
                    'group_power_status' => $uuid2GroupPowerStatus[$uuid] ?? 1,
                    'online_status' => $uuid2OnlineStatus[$uuid] ?? 1,
                ];
            }
        }

        if (!empty($insertData)) {
            $this->app->db->name('data_city_user_relation')->insertAll($insertData);
        }

        if (!empty($deleteIds)) {
            $this->app->db->name('data_city_user_relation')->whereIn('id', $deleteIds)->delete();
        }

        return true;
    }

    /**
     * 获取城市员工关联配置
     * @param $cityRelationId
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getRelation($cityRelationId)
    {
        $cityUserRelations = $this->app->db->name('data_city_user_relation')->where('city_relation_id', $cityRelationId)->select()->toArray();
        WorkUserService::instance()->buildByUid($cityUserRelations, 'uuid', 'user', 'id,username,name');
        return $cityUserRelations;
    }

    /**
     * 匹配城市ID
     * @param $province
     * @param $city
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function mathCityRelationId($province, $city)
    {
        $cityRelationId = 0;
        $cityRelations = $this->app->db->name('data_city_relation')->where('from_province', $province)->where('status', 1)->select()->toArray();
        foreach ($cityRelations as $cityRelation) {
            if ($cityRelation['from_city'] == $city) {
                $cityRelationId = $cityRelation['id'];
                $toProvince = $cityRelation['to_province'];
                $toCity = $cityRelation['to_city'];
            }
        }
        if (empty($cityRelation)) {
            foreach ($cityRelations as $cityRelation) {
                if ($cityRelation['from_city'] == '') {
                    $cityRelationId = $cityRelation['id'];
                    $toProvince = $cityRelation['to_province'];
                    $toCity = $cityRelation['to_city'];
                }
            }
        }

        return [$cityRelationId, $toProvince ?? '', $toCity ?? ''];
    }

    /**
     * 匹配数据返回对接人员工ID
     * @param $cityRelationId
     * @return mixed|void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function distributeDockingUuid($cityRelationId, $fromProvince, $fromCity)
    {
        // 根据匹配的城市ID获取员工列表
        /*if ($cityRelationId) {
            $dataCityRelation = $this->app->db->name('data_city_relation')->where('id', $cityRelationId)->findOrEmpty();
            return $dataCityRelation['uuid'] ?? 0;
        }

        if (empty($dataCityRelation)) {
            return sysdata('DefaultCityRelation')['uuid'];
        }*/

        $uuidDocking = $this->getUuidDockingNameByProvinceAndCity($fromProvince, $fromCity);
        return $uuidDocking['id'] ?? 0;
    }

    /**
     * 匹配数据返回城市负责人员工ID
     * @param $cityRelationId
     * @return int|mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function distributeCityUuid($cityRelationId)
    {
        // 根据匹配的城市ID获取员工列表
        if (!$cityRelationId) {
            return sysdata('DefaultCityUuid');
        }

        $cityUserRelations = $this->app->db->name('data_city_user_relation')->where('city_relation_id', $cityRelationId)->where('online_status', 0)->select()->toArray();

        // 筛选已经打卡的员工，才有资格分配到
        $todayStartTimestamp = strtotime(date('Y-m-d 00:00:00'));
        $users = $this->app->db->name('work_user')->whereIn('id', array_column($cityUserRelations, 'uuid'))->select()->toArray();
        $chunkUser = array_column($users, 'user_id');
        $checkInUsers = FeiShuService::instance()->checkInRecords($todayStartTimestamp, time(), $chunkUser);

        foreach ($users as $user) {
            if (in_array($user['user_id'], $checkInUsers)) {
                $userIds[] = $user['id'];
            }
        }

        // 筛选没有被品质冻结的员工
        if (!empty($userIds)) {
            $reworkRecords = $this->app->db->name('rework_record')->where('is_unlock', 0)->whereIn('uuid_city', $userIds)->select()->toArray();
            $reworkRecordUserIds = array_column($reworkRecords, 'uuid_city');
            foreach ($userIds as $key => $userId) {
                if (in_array($userId, $reworkRecordUserIds)) {
                    unset($userIds[$key]);
                }
            }
        }

        // 去除前线运营 和 去除未打卡员工
        foreach ($cityUserRelations as $key => $cityUserRelation) {
            if (isset($cityUserRelation['online_status']) && $cityUserRelation['online_status']) {
                unset($cityUserRelations[$key]);
            } else if (!in_array($cityUserRelation['uuid'], $userIds ?? [])) {
                unset($cityUserRelations[$key]);
            }
        }

        // 获取已经分配的数据
        $records = $this->app->db->name('data_record')
            ->fieldRaw('count(*) as count')
            ->where('create_at', '>', date('Y-m-d 00:00:00'))
            ->where('city_relation_id', $cityRelationId)
            ->field('uuid_city')
            ->group('uuid_city')
            ->select()->toArray();
        foreach ($records as $record) {
            $uuid2Count[$record['uuid_city']] = $record['count'];
        }

        foreach ($cityUserRelations ?? [] as $key => $cityUserRelation) {
            if (isset($uuid2Count[$cityUserRelation['uuid']])) {
                $cityUserRelations[$key]['count'] = bcdiv($uuid2Count[$cityUserRelation['uuid']], $cityUserRelation['percentage'], 4);
            } else {
                $cityUserRelations[$key]['count'] = '0.0000';
            }
        }

        array_multisort(array_column($cityUserRelations, 'count'), SORT_ASC, $cityUserRelations);

        if (empty($cityUserRelations[0]['uuid'])) {
            Log::error('匹配不到员工 ' . json_encode($checkInUsers));
        }

        return $cityUserRelations[0]['uuid'] ?? 0;
    }

    /**
     * 计算喷漆费用
     * @param $data
     * @return mixed
     */
    public function calcPaintPrice($record, $data)
    {
        $carVehicleType = $this->app->db->name('car_vehicle_types')->where('id', $data['car_vehicle_type_id'] ?? 0)->findOrEmpty();
        if (intval($data['end_paint_status']) === 1) {
            $data['platform_price'] = $carVehicleType['platform_price'] ?? sysconf('data.platform_price');
        } else {
            $data['platform_price'] = $carVehicleType['platform_double_price'] ?? sysconf('data.platform_double_price');
        }
        if (intval($data['end_paint_status']) === 1) {
            $data['painter_price'] = ($carVehicleType['painter_price'] ?? sysconf('data.painter_price'));
        } else {
            $data['painter_price'] = ($carVehicleType['painter_double_price'] ?? sysconf('data.painter_double_price'));
        }

        return $data;
    }

    /**
     * @param $toProvince
     * @param $toCity
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getUuidDockingNameByProvinceAndCity($fromProvince, $fromCity): array
    {
        $region = $this->app->db->name('base_postage_region')->where('name', $fromProvince)->findOrEmpty();

        if (!$region) {
            $cityUuid = sysdata('DefaultDockingUuid');
        } else {
            $region = $this->app->db->name('base_postage_region')->where('pid', $region['id'])->where('name', $fromCity)->findOrEmpty();
            $cityRelation = $this->app->db->name('data_city_docking_config')->where('id', $region['city_docking_config_id'])->where('status', 1)->where('deleted', 0)->findOrEmpty();
            if ($cityRelation && !empty($region['uuid_docking'])) {
                $cityUuid = $region['uuid_docking'];
            } else {
                $cityUuid = sysdata('DefaultDockingUuid');
            }
        }

        $workUser = $this->app->db->name('work_user')->where('id', $cityUuid)->findOrEmpty();

        return [
            'id' => $workUser['id'] ?? 0,
            'uuid_docking_name' => $workUser['name'] ?? '',
        ];
    }
}